﻿using TechTalk.SpecFlow;
using Xunit;
using Sai.Core.Introspection;
using Sai.Test.TestDataBuilders;

namespace ApiDiff.Specs.Steps
{
	[Binding]
	public class ConstructorDeclarationSteps
	{
		const string oldVersionKey = "oldType";
		const string newVersionKey = "newType";

		[Given(@"I have a class named (.*) in namespace (.*)")]
		public void GivenIHaveAClassNamedInNamespace(string className, string namespaceName)
		{
			TypeName typeName = new TypeName(string.Format("{0}.{1}", namespaceName, className));

			ScenarioContext.Current.Set<TypeName>(typeName);
		}

		[Given(@"it has no constructor in the old version")]
		public void GivenItHasNoConstructorInTheOldVersion()
		{
			var typeName = ScenarioContext.Current.Get<TypeName>();

			var emptyCollection = new InstanceConstructorDeclarationCollection();

			ScenarioContext.Current.Set<InstanceConstructorDeclarationCollection>(emptyCollection, oldVersionKey);
		}

		[Then(@"there is no difference between the classes versions")]
		public void ThenThereIsNoDifferenceBetweenTheClassesVersions()
		{
			var oldVersion = ScenarioContext.Current.Get<InstanceConstructorDeclarationCollection>(oldVersionKey);
			var newVersion = ScenarioContext.Current.Get<InstanceConstructorDeclarationCollection>(newVersionKey);

			ScenarioContext.Current.Pending();

			//var code = newVersion.DifferencesFrom(oldVersion);

			//Assert.False(code.HasAnyChanges);
		}

		[When(@"I add a default constructor to the new version")]
		public void WhenIAddADefaultConstructorToTheNewVersion()
		{
			var typeName = ScenarioContext.Current.Get<TypeName>();

			var constructor = InstanceConstructorDeclarationBuilder.InstanceConstructor()
								.ForType(typeName)
								.Build();

			var singleItemCollection = new InstanceConstructorDeclarationCollection();

			singleItemCollection.Add(constructor);

			ScenarioContext.Current.Set<InstanceConstructorDeclarationCollection>(singleItemCollection, newVersionKey);
		}

		[Given(@"it has a default constructor in the old version")]
		public void GivenItHasADefaultConstructorInTheOldVersion()
		{
			var typeName = ScenarioContext.Current.Get<TypeName>();

			var constructor = InstanceConstructorDeclarationBuilder.InstanceConstructor()
								.ForType(typeName)
								.Build();

			var singleItemCollection = new InstanceConstructorDeclarationCollection();

			singleItemCollection.Add(constructor);

			ScenarioContext.Current.Set<InstanceConstructorDeclarationCollection>(singleItemCollection, oldVersionKey);
		}

		[When(@"I remove the constructor to the new version")]
		public void WhenIRemoveTheConstructorToTheNewVersion()
		{
			var typeName = ScenarioContext.Current.Get<TypeName>();

			var emptyCollection = new InstanceConstructorDeclarationCollection();

			ScenarioContext.Current.Set<InstanceConstructorDeclarationCollection>(emptyCollection, newVersionKey);
		}

		[Then(@"there is an addition to the new version")]
		public void ThenThereIsAnAdditionToTheNewVersion()
		{
			var oldVersion = ScenarioContext.Current.Get<InstanceConstructorDeclarationCollection>(oldVersionKey);
			var newVersion = ScenarioContext.Current.Get<InstanceConstructorDeclarationCollection>(newVersionKey);

			ScenarioContext.Current.Pending();

			//var code = newVersion.DifferencesFrom(oldVersion);

			//Assert.True(code.HasAnyChanges);
			//Assert.True(code.HasAdditions);
			//Assert.Equal(1, code.Additions.Count);
		}

		[When(@"I add a constructor with arguments to the new version")]
		public void WhenIAddAConstructorWithArgumentsToTheNewVersion()
		{
			var typeName = ScenarioContext.Current.Get<TypeName>();
			var collection = new InstanceConstructorDeclarationCollection();

			collection.Add(InstanceConstructorDeclarationBuilder
								.InstanceConstructor()
								.ForType(typeName)
								.Build());

			collection.Add(InstanceConstructorDeclarationBuilder
								.InstanceConstructor()
								.ForType(typeName)
								.WithParameter(new Parameter(new TypeName("Int32")))
								.Build());

			ScenarioContext.Current.Set<InstanceConstructorDeclarationCollection>(collection, newVersionKey);
		}
	}
}
